/*
 * Copyright (c) 2012,东方口岸科技有限公司
 * All rights reserved.
 * 文件名称：RouterImpl.java
 * 摘    要：
 * 版本：1.0
 * 作    者：fengzhiyong
 */
package com.cneport.transfer.router;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.cneport.transfer.message.Message;
import com.cneport.transfer.router.MessageRouter;
import com.cneport.transfer.router.model.Node;
import com.cneport.transfer.router.model.RouterMessage;
import com.cneport.transfer.router.model.RouterType;
import com.cneport.transfer.router.model.User;
import com.cneport.transfer.router.support.ClientFinderImpl;
import com.cneport.transfer.router.support.NodeFinderImpl;

@Component
public class MessageRouterImpl implements MessageRouter {

    @Autowired 
    private NodeFinderImpl nodeFinder;

    @Autowired
    private ClientFinderImpl clientFinderImpl; 
    @Value("${Server.Local.SenderId}")
    private String PNodeID;
    
    private static Logger logger = Logger.getLogger(MessageRouterImpl.class);

    public RouterMessage route(Message<?> message) {
    	
        RouterMessage routerMessage = new RouterMessage();
        String RNodeID;// 接收节点ID
        String RClientID;// 接收客户端ID
       // String PNodeID;// 平台的NodeID
        String SNodeID;// 发送节点ID
        String SClientID;// 发送客户端ID
        //PNodeID = "NF1101";// 之后由配置文件获取得到
        String[] senderIdAndNode = message.getSenderId().split("@");
        SNodeID = senderIdAndNode[1];
        SClientID = senderIdAndNode[0];
        // 判断当前平台是否与发送地址中的平台编号相同，相同需要校验发送ID是否存在，不存在抛异常
        if (SNodeID.equals(PNodeID)) {
            if (!validateClient(SClientID)) {
                throw new SenderIsNotExistException(SClientID);
            }
        }
        String[] receiverIdAndNode = message.getReceiverId().split("@");
        RNodeID = receiverIdAndNode[1];
        RClientID = receiverIdAndNode[0];
        // 判断当前平台是否与接收地址中的平台编号相同，相同需要校验接收ID是否存在，不存在抛异常
        if (RNodeID.equals(PNodeID)) {
            if (!validateClient(RClientID)) {
                throw new ReceiverIsNotExistException(RClientID);
            } else {
                routerMessage.setRouterType(RouterType.user);
                routerMessage.setUser(clientFinderImpl.findClient(RClientID));
                routerMessage.setReceiverId(message.getReceiverId());
                routerMessage.setSenderId(message.getSenderId());
                return routerMessage;
            }
        } else {        	
            List<Node> nodeList2 = nodeFinder.findChildrenNodes(PNodeID);
            boolean flag = false;
            for (Node node1 : nodeList2) {
                if (RNodeID.equals(node1.getNodeId())) {
                    flag = true;
                }
            }
            if (flag) {
                List<Node> nodeList = nodeFinder
                        .findFirshChildrenNodes(PNodeID);
                for (Node node1 : nodeList) {
                	if(RNodeID.equals(node1.getNodeId())){
                		routerMessage.setRouterType(RouterType.node);
                        routerMessage.setNode(node1);
                        return routerMessage;
                	}                	
                    List<Node> nodeList1 = nodeFinder.findChildrenNodes(node1
                            .getNodeId());
                    for (Node node : nodeList1) {
                        if ( RNodeID.equals(node.getNodeId())) {
                            routerMessage.setRouterType(RouterType.node);
                            routerMessage.setNode(node1);
                            return routerMessage;
                        }
                    }

                }
                routerMessage.setRouterType(RouterType.node);
                routerMessage.setNode(nodeList.get(0));
                return routerMessage;

            } else {
                List<Node> nodeList = nodeFinder.findNextNode(PNodeID);
                List<Node> nodeList1 = new ArrayList<Node>();
                if (nodeList != null && nodeList.size() >= 0) {
                    for (Node node : nodeList) {
                        if(RNodeID == node.getNodeId()
                                || RNodeID.equals(node.getNodeId())){
                            routerMessage.setRouterType(RouterType.node);
                            routerMessage.setNode(node);
                            return routerMessage;  
                        }
                        nodeList1 = nodeFinder.findChildrenNodes(node
                                .getNodeId());
                        for (Node node1 : nodeList1) {
                            if (RNodeID == node1.getNodeId()
                                    || RNodeID.equals(node1.getNodeId())) {
                                routerMessage.setRouterType(RouterType.node);
                                routerMessage.setNode(node);
                                return routerMessage;
                            }
                        }
                    }
                    routerMessage.setRouterType(RouterType.none);
                    return routerMessage;

                } else {
                    logger.info("==================");
                    Node node = nodeFinder.findParentNode(PNodeID);
                    if (node == null) {
                        routerMessage.setRouterType(RouterType.none);
                        return routerMessage;
                    } else {
                        routerMessage.setRouterType(RouterType.node);
                        routerMessage.setNode(node);
                        return routerMessage;
                    }
                }
            }

        }
    }

    private boolean validateClient(String clientId) {
        User user = clientFinderImpl.findClient(clientId);
        if (user != null) {
            return true;
        }
        return false;
    }

}
